#include <iostream>
#include <string>

#define __TEST__
#include "block_queue.hpp"
#include "task.hpp"

#include <cstdlib>
#include <ctime>

#include <unistd.h>
#include <pthread.h>

std::string opers = "+-*/%#";

void* Consumer(void* args)
{
    BlockQueue<Task>* bq = static_cast<BlockQueue<Task>*>(args);
    while (true)
    {
        //消费
        //int data = bq->pop();
        //std::cout << "消费了一个数据: " << data << std::endl;
        //sleep(1);
        
        Task task = bq->pop();
        // task.run();
        task();
        std::cout << "thread id: " << pthread_self();
        std::cout << " 消费了一个任务: " << task.get_result() << std::endl;
    }
    return nullptr;
}

void* Productor(void* args)
{
    BlockQueue<Task>* bq = static_cast<BlockQueue<Task>*>(args);
    while (true)
    {
        //生产
        //std::cout << "生产了一个数据: " << data << std::endl;
        //bq->push(data);
        //sleep(1);

        int left = rand() % 10;
        int right = rand() % 10;
        char oper = opers[rand() % opers.size()];

        Task task(left, right, oper);
        std::cout << "thread id: " << pthread_self();
        std::cout << " 生产了一个任务: " << task.get_task() << std::endl;
        bq->push(std::move(task));
        sleep(1);
    }
    return nullptr;
}

int main()
{
    srand((unsigned int)time(nullptr));

    BlockQueue<Task>* bq = new BlockQueue<Task>;

    pthread_t c[3], p[5];
    for (int i = 0; i < 3; ++i)
        pthread_create(c + i, nullptr, Consumer, (void*)bq);
    for (int i = 0; i < 5; ++i)
        pthread_create(p + i, nullptr, Productor, (void*)bq);

    for (int i = 0; i < 3; ++i)
        pthread_join(c[i], nullptr);
    for (int i = 0; i < 5; ++i)
        pthread_join(p[i], nullptr);
    delete bq;

    return 0;
}